<!--
 * @Author: lizhenyu
 * @Date: 2020-08-18 09:57:47
 * @LastEditors: lizhenyu
 * @LastEditTime: 2020-08-18 11:44:05
 * @Description: Generating SKU by selecting specifications
 * @FilePath: \brand-apps-operation-portal\src\views\generateSku\index.vue
-->
<template>
  <div class="sku">
    <el-form ref="form" :model="skuForm" label-width="80px">
      <el-button
        size="mini"
        type="primary"
        style="margin-bottom: 20px;margin-left: 20px;"
        @click="addDialogForm = true"
      >添加商品规格</el-button>
      <!-- 商品属性 -->
      <el-form-item label="属性类型">
        <el-select v-model="skuForm.value" placeholder="请选择">
          <el-option
            v-for="item in options"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          ></el-option>
        </el-select>
      </el-form-item>
      <!-- 商品规格 -->
      <el-form-item label="商品规格">
        <div style="background-color: #f8f9fd;">
          <div style="margin-left: 20px;" v-for="(item, index) in analogList" :key="index">
            <label>{{item.name}}:</label>
            <el-checkbox-group v-model="checkList[index].list" :ref="item.keyName" @change="delBtnDisplay(item, index)">
              <el-checkbox v-for="(itemT, indexT) in item.list" :key="indexT" :label="itemT"></el-checkbox>
              <div style="display: inline-block;" v-if="displayList[index].existence">
                <el-button
                  size="mini"
                  type="text"
                  @click="delChecked(item,index)"
                  class="el-icon-delete delBtn"
                >删除</el-button>
              </div>
            </el-checkbox-group>
            <el-input size="small" style="width: 300px" v-model="skuForm.addValueList[index].value">
              <el-button slot="append" @click="addListValue(item,index)">添加</el-button>
            </el-input>
            <div style="position: relative; top: -76px; left: 187px; display: inline-block;">
              <el-button type="primary" size="mini" @click="delGoodsSpecs(item,index)">删除</el-button>
            </div>
          </div>
        </div>
      </el-form-item>
    </el-form>
    <!-- sku生成表格-->
    <el-table :data="skuObjList" style="width: 83%; margin-left: 80px;">
      <el-table-column
        v-for="(item, index) in tableSkuData"
        :key="index"
        :label="item.name"
        :prop="item.keyName"
        min-width="80px"
      ></el-table-column>
      <el-table-column label="价格" min-width="80px">
        <template slot-scope="scope">
          <el-input v-model="scope.row.price"></el-input>
        </template>
      </el-table-column>
      <el-table-column label="库存" min-width="80px">
        <template slot-scope="scope">
          <el-input v-model="scope.row.stock"></el-input>
        </template>
      </el-table-column>
      <el-table-column label="库存预警值" min-width="100px">
        <template slot-scope="scope">
          <el-input v-model="scope.row.warningValue"></el-input>
        </template>
      </el-table-column>
      <el-table-column label="SKU编号" min-width="80px">
        <template slot-scope="scope">
          <el-input v-model="scope.row.skuNum"></el-input>
        </template>
      </el-table-column>
      <el-table-column fixed="right" label="操作" min-width="80px">
        <template slot-scope="scope">
          <el-button
            @click.native.prevent="deleteRow(scope.$index, skuObjList)"
            type="text"
            size="small"
          >移除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 添加规格的弹框 -->
    <el-dialog title="商品的规格" :visible.sync="addDialogForm">
      <el-form :model="SkuSpecsForm" label-position="left" label-width="70px">
        <el-form-item label="规格名称">
          <el-input style="width: 200px;" v-model="SkuSpecsForm.specsName" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="键名">
          <el-input style="width: 200px;" v-model="SkuSpecsForm.specsKeyName" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="规格属性">
          <el-tag
            :key="tag"
            size="medium"
            style="margin-right: 10px;"
            v-for="tag in SkuSpecsForm.specsList"
            closable
            :disable-transitions="false"
            @close="handleClose(tag)"
          >{{tag}}</el-tag>
          <el-input
            class="input-new-tag"
            style="width: 100px;"
            v-if="inputVisible"
            v-model="inputValue"
            ref="saveTagInput"
            size="small"
            @keyup.enter.native="handleInputConfirm"
            @blur="handleInputConfirm"
          ></el-input>
          <el-button v-else class="button-new-tag" size="small" @click="showInput">+ New Tag</el-button>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="addDialogForm = false">取 消</el-button>
        <el-button type="primary" @click="addSkuSpecsForm">确 定</el-button>
      </div>
    </el-dialog>
    <el-button
      style="margin-top: 20px; margin-left: 80px"
      type="primary"
      size="mini"
      @click="handleClick"
    >刷新列表</el-button>
  </div>
</template>

<script>
export default {
  name: 'SKU',
  data () {
    return {
      inputVisible: false,
      inputValue: '',
      // 商品的类型
      options: [
        {
          value: '1',
          label: '手机数码-手机通讯'
        }
      ],
      // 创建sku数据的键
      skuKey: '',
      // sku表单
      skuForm: {
        value: '1',
        addValueList: [{ value: '' }, { value: '' }]
      },
      // 假数据
      analogList: [
        {
          name: '颜色',
          keyName: 'color',
          list: ['红色', '白色', '蓝色', '黑色']
        },
        {
          name: '容量',
          keyName: 'capacity',
          list: ['16G', '32G', '64G', '128G']
        }
      ],
      // 表格中Sku的值
      tableSkuData: [],
      // 选中的值
      checkList: [
        {
          name: '颜色',
          keyName: 'color',
          list: []
        },
        {
          name: '容量',
          keyName: 'capacity',
          list: []
        }],
      // sku的数据
      skuList: [],
      // 转换成功后的sku数据
      skuObjList: [],
      // 按钮是否显示和隐藏
      displayList: [{ existence: false }, { existence: false }],
      // 弹框商品规格的表单
      SkuSpecsForm: {
        specsName: '',
        specsKeyName: '',
        specsList: []
      },
      // 弹框显示
      addDialogForm: false
    }
  },
  methods: {
    handleClick () {
      // 先清空数据，保证连续点击按钮，数据不会重复
      this.skuList = []
      this.skuArray = []
      // 将选中的规格组合成一个大数组
      this.checkList.forEach((element) => {
        // 如果选中的列表中有值  就将获取整个数组
        if (element.list.length > 0) {
          this.skuArray.push(element)
        }
      })

      this.tableSkuData = this.skuArray
      // 勾选了规格，才调用方法
      if (this.skuArray.length > 0) {
        this.getSkuData({ list: this.skuArray })
        this.getSkuDataType()
      } else {
        this.skuObjList = []
        return this.$notify({
          title: '警告',
          message: '请选择规格',
          type: 'warning'
        })
      }
      // 遍历选中列表  若其中有一项为空 就不能显示数据
      const checkListArr = []
      this.checkList.forEach((el, index) => {
        if (el.list.length > 0) {
          checkListArr.push(el.list)
        }
      })

      // 判断数据中是否没有或者只有一条数据
      if (checkListArr.length === 0) {
        return this.$notify({
          title: '警告',
          message: '规格中必须含有一个可选值',
          type: 'warning'
        })
      }
    },

    // 递归获取每条SKU数据
    getSkuData ({ skuArr = [], i = 0, list }) {
      for (let j = 0; j < list[i].list.length; j++) {
        if (i < list.length - 1) {
          skuArr[i] = list[i].list[j]
          // 递归循环
          this.getSkuData({ skuArr, i: i + 1, list })
        } else {
          // 扩展运算符，连接两个数组
          this.skuList.push([...skuArr, list[i].list[j]])
        }
      }
    },

    // 转化数据
    getSkuDataType () {
      const dataTypeArr = []
      this.skuList.forEach((el) => {
        const newObj = {}
        this.skuKey = ''
        // 把数据转化为对象
        el.forEach((e, i) => {
          // 新的键值结构
          this.skuKey += `${e}`
          newObj[this.tableSkuData[i].keyName] = e
        })
        // 新建一个键值 用于分辨数据的归属
        newObj.keyName = this.skuKey.trim().split(' ').join('-')
        // 一些初始化数据
        // 规格的类型
        newObj.specificationType = ''
        // table中的一些属性
        newObj.price = ''
        newObj.warningValue = ''
        newObj.skuNum = ''
        newObj.stock = ''
        // 获取新的表格数据
        dataTypeArr.push(newObj)
      })
      // 调用比较表格的数据的方法
      this.compareTableData(dataTypeArr)
    },

    // 新旧值比较
    compareTableData (dataTypeArr) {
      // 遍历数组中所有的值
      dataTypeArr.forEach((el, index) => {
        // 查找表格中数据和该数组中的数据是否是一样的
        const dataIndex = this.skuObjList.findIndex(
          (item) => el.keyName === item.keyName
        )
        // 判断返回值
        if (dataIndex !== -1) {
          // 进行一个数据的替换
          dataTypeArr[index] = this.skuObjList[dataIndex]
        }
      })
      this.skuObjList = dataTypeArr
    },

    // 删除选中规格
    delChecked (item, index) {
      // 创建一个新的数组 用于接收list的值
      const checkedArr = this.$refs[item.keyName][0]
      const checkedList = this.$_.cloneDeep(checkedArr.value)
      // 判断选中的数据是不是空的
      if (checkedList && checkedList.length === 0) return
      const skuFormListData = this.analogList[index].list
      const checkedListValue = this.checkList[index].list
      // 遍历被选中的数组
      checkedList.forEach((el, i) => {
        // 查询list数组中的值
        const delCheckList = skuFormListData.findIndex((itemA) => itemA === el)
        // 判断返回值
        if (delCheckList !== -1) {
          // 将选中的数据进行删除
          if (skuFormListData.length === 1) {
            // 提示框
            return this.$notify({
              title: '提示',
              message: this.$createElement('i', '规格必须有一个可选择项')
            })
          }
          // 删除原数据中的规格
          skuFormListData.splice(delCheckList, 1)
          this.displayList[index].existence = true
        }
        // 查找选中的数据的索引
        const delCheckedIndex = checkedListValue.findIndex(item => item === el)
        // 如果找得到
        if (delCheckedIndex !== -1) {
          // 就删除选中的数据
          checkedListValue.splice(delCheckedIndex, 1)
        }
      })
    },

    // 删除按钮的显示效果
    delBtnDisplay (item, index) {
      // 当点击选项的时候  获取该选项的值  然后根据是否选中  来判断删除按钮是否显示
      const checkedArr = this.$refs[item.keyName][0]
      const checkedList = this.$_.cloneDeep(checkedArr.value)
      // 开始是没有选中的状态  所以隐藏删除按钮
      this.displayList[index].existence = false
      // 判断删除按钮是否显示
      // 如果规格被选中 就显示 删除按钮
      if (checkedList.length > 0) {
        this.displayList[index].existence = true
      }
    },

    // 删除商品的属性
    delGoodsSpecs (item, index) {
      // 删除商品的属性  选中的属性也要被删除
      this.analogList.splice(index, 1)
      this.checkList.splice(index, 1)
    },

    // 添加选项
    addListValue (item, index) {
      // 判断是否为空
      if (this.skuForm.addValueList[index].value !== '') {
        // 不为空就把弹框表单的数据加到原数据中
        this.analogList[index].list.push(
          this.skuForm.addValueList[index].value
        )
        this.displayList.push({
          existence: false
        })
        // this.displayList[index].existence = true
        this.skuForm.addValueList[index].value = ''
      }
    },

    // 添加规格
    addSkuSpecsForm () {
      this.displayList.push({
        existence: false
      })
      this.checkList.push({
        name: this.SkuSpecsForm.specsName,
        keyName: this.SkuSpecsForm.specsKeyName,
        list: []
      })
      this.skuForm.addValueList.push({
        value: ''
      })
      // 判断是否有值
      if (
        this.SkuSpecsForm.specsName &&
        this.SkuSpecsForm.specsKeyName &&
        this.SkuSpecsForm.specsList
      ) {
        // 添加输入的值
        this.analogList.push({
          name: this.SkuSpecsForm.specsName,
          keyName: this.SkuSpecsForm.specsKeyName,
          list: this.SkuSpecsForm.specsList
        })
        // 将表单的各项数据变成空
        // 弹框关闭
        this.addDialogForm = false
        // 添加之后重置输入框
        this.SkuSpecsForm.specsName = ''
        this.SkuSpecsForm.specsKeyName = ''
        this.SkuSpecsForm.specsList = []
      }
    },

    // 删除表格行数据
    deleteRow (index, rows) {
      rows.splice(index, 1)
    },

    // 删除tag
    handleClose (tag) {
      this.SkuSpecsForm.specsList.splice(
        this.SkuSpecsForm.specsList.indexOf(tag)
      )
    },

    // 展示tag
    showInput () {
      this.inputVisible = true
      this.$nextTick((_) => {
        this.$refs.saveTagInput.$refs.input.focus()
      })
    },

    // 添加tag
    handleInputConfirm () {
      const inputValue = this.inputValue
      if (inputValue) {
        this.SkuSpecsForm.specsList.push(inputValue)
      }
      // 关闭tag框
      this.inputVisible = false
      // 清空数据
      this.inputValue = ''
    }
  }
}
</script>

<style lang="scss" scoped>
.delBtn {
  position: relative;
  top: 3px;
  right: -4px;
}
</style>
